<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <title>葡萄藤PPT</title>

    <link rel="stylesheet" href="../css/reveal/reveal.css">

    <!-- PPT主题，可以在/css/reveal/theme/中选择其他主题，目前暂时只能使用该模板 -->
    a
    <link rel="stylesheet" href="../css/reveal/theme/ptt.css">

    <!-- syntax highlighting 代码高亮主题 -->
    <link rel="stylesheet" href="../lib/reveal/css/zenburn.css">

    <!-- 打印和PDF输出样式 -->
    <script>
        var link = document.createElement('link');
        link.rel = 'stylesheet';
        link.type = 'text/css';
        link.href = window.location.search.match(/print-pdf/gi) ? '../css/reveal/print/pdf.css' : '../css/reveal/print/paper.css';
        document.getElementsByTagName('head')[0].appendChild(link);
    </script>
</head>

<body>
<img src="../img/demo/logo.png" alt="" usemap="#pttmap" class="base-logo">
<map name="pttmap">
    <area shape="rect" coords="0,0,276,58" href="http://www.jnshu.com" alt="" target="_blank"/>
</map>
<div class="reveal">
    <div class="slides" style="text-align: left">
        <section>
            <h3>AngularJS中的依赖注入</h3>
            <h4>小课堂【深圳】</h4>
            <p>分享人：蓝裕伟</p>
        </section>
        <section>
            <p>目录</p>
            <p>1.背景介绍</p>
            <p>2.知识剖析</p>
            <p>3.常见问题</p>
            <p>4.解决方案</p>
            <p>5.编码实战</p>
            <p>6.扩展思考</p>
            <p>7.参考文献</p>
            <p>8.更多讨论</p>
        </section>
        <section>
            <section>
                <h3>1.背景介绍</h3>
            </section>
            <section>
                <p>
                    依赖注入式AngularJS的重要特性之一，依赖注入简化了Angular解析模块/组件之间依赖的过程。 <br>
                    什么是依赖注入 <br>
                    wiki 上的解释是：依赖注入（Dependency Injection，简称DI）是一种软件设计模式，在这种模式下，
                    一个或更多的依赖（或服务）被注入（或者通过引用传递）到一个独立的对象（或客户端）中，然后成为了该客户端状态的一部分。
                    该模式分离了客户端依赖本身行为的创建，这使得程序设计变得松耦合，并遵循了依赖反转和单一职责原则。与服务定位器模式形
                    成直接对比的是，它允许客户端了解客户端如何使用该系统找到依赖 . <br>
                    一句话 --- 没事你不要来找我，有事我会去找你。
            </section>
        </section>
        <section>
            <section>
                <h3>2.知识剖析</h3>
            </section>
            <section>
                <h4>angular依赖注入机制</h4>
                <p>AngularJS 提供了5个核心组件用来作为依赖注入：  <br>
                    value<br>
                    factory<br>
                    service<br>
                    provider<br>
                    constant</p>
            </section>
            <section>
                <h4>$provide (供应商)</h4>
                $provide服务负责告诉Angular如何创造一个新的可注入的东西：即服务。服务会被叫做供应商的东西来定义，我们可以使用$provide来创建一个供应商。<br>
                我们需要使用$provide中的provider()方法来定义一个供应商，同时也可以通过要求$provide被注入到一个应用的config函数中来获得$provide服务。<br>
                <img src="../img/js-9/312687970-55cdb6623e708.png" alt="">
            </section>
            <section>
                <h3>$provide</h3>
                <p>
                    $provide是一个服务，在Auto模块中.这个服务下面的方法用来定义供应商。而供应商是用来提供服务，服务就是我们说的依赖注入的具体
                </p>
            </section>
            <section  style="font-size:25px;" >
                <p>看一个例子：</p>
                <pre style="width:100%;">
                        <code style="font-size:25px;" class="">
    angular.module（‘app’，[]）.config(function($provide) {
  $provide.provider('greeting', function() {
    this.$get = function() {
      return function(name) {
        alert("Hello, " + name);
      };
    };
  });
});
     </code>
                </pre>
                在上面的例子中我们为一个服务定义了一个叫做greeting的新provider。 我们可以把一个叫做greeting的变量注入到任何可注入的函数中
                （例如控制器）然后Angular就会调用这个provider的$get函数来返回这个服务的一个实例。在上面的例子中，被注入的是一个函数，
                它接受一个参数并且根据这个参数alert一条信息。我们可以像下面这样使用它：
            </section>
            <section>
      <pre style="width:100%;">
                        <code style="font-size:25px;" class="">
app.controller('MyCtrl', function($scope, greeting) {
  $scope.onClick = function() {
greeting('Ford Prefect');
  };
});
     </code>
                </pre>
            </section>
            <section>
                <h4>定义供应商的方法</h4>
                <p>1、Constant</p>
                <p>Constant定义常量，Constant定义的值不应该被改变，它可以被注入到任何地方，但是不能被装饰器(decorator)装饰</p>
                <pre style="height: 100%;"><code style="min-height: 100%;font-size:30px;">
 var app = angular.module('app', []);

app.config(function ($provide) {
  $provide.constant('myConstant', 'The Matrix');
});

                        </code></pre>
                语法糖：<br>
                <pre style="height: 100%;"><code style="min-height: 100%;font-size:30px;">
       app.constant('myConstant', 'The Matrix');
                        </code></pre>
            </section>

            <section>
                <h3>2、Value</h3>
                <p>Value可以是string,number甚至function,它和constant的不同之处在于，它可以被修改，不能被注入到config中，但是它可以被decorator装饰</p>
                </code></pre>
                <pre style="height: 100%;">
                    <code style="min-height: 100%;font-size:30px;">
 var app = angular.module('app', []);

app.config(function ($provide) {
  $provide.value('myValue', 'The Matrix')
});

                        </code>
                </pre>
                语法糖：<br>
                <pre style="height: 100%;"><code style="min-height: 100%;font-size:20px;">
   app.value('myValue', 'The Matrix');
                        </code></pre>


            </section>
            <section>
                <h3>3、Service</h3>
                <p style="font-size: 20px">Service是一个可注入的构造器，在AngularJS中它是单例的，用它在Controller中通信或者共享数据都很合适.
                    在service里面可以不用返回东西，因为AngularJS会调用new关键字来创建对象。
                </p>
                <pre style="">
                        <code style="min-height: 100%;font-size: 30px;" class="">
var app = angular.module('app' ,[]);

app.config(function ($provide) {
  $provide.service('myService', function () {
    this.title = 'The Matrix';
  });
});
                        </code>
                    </pre>
                语法糖：<br>
                <pre style="height: 100%;"><code style="min-height: 100%;font-size:30px;">
app.service('myService', function () {
  this.title = 'The Matrix';
});
                        </code></pre>

            </section>
            <section>
                <h5>4、Factory</h5>

                <p style="font-size: 20px"> Factory是一个可注入的function，它和service的区别就是：factory是普通function，而service是一个构造器(constructor)，
                    Angular在调用service时会用new关键字，而调用factory时只是调用普通的function，所以factory可以返回任何东西，而service可以不返回.
                    factory可以返回任何东西，它实际上是一个只有$get方法的provider</P>
                <pre style="height: 100%;"><code style="min-height: 100%;font-size:30px;">

var app = angular.module('app', []);

app.config(function ($provide) {
  $provide.factory('myFactory', function () {
    return {
      title: 'The Matrix'
    }
  });
});
                        </code></pre>

                <pre style="height: 100%;"><code style="min-height: 100%;font-size:30px;">
                    //  语法糖：<br>
app.factory('movie', function () {
  return {
    title: 'The Matrix'
  }
});
                        </code></pre>

            </section>
            <section>
                <h4>Provider</h4>
                <p>provider是value，Service,Factory的老大，除了constant其它都是provider的封装。
                    provider必须有一个$get方法，当然也可以说provider是一个可配置的factory</p>
                </code></pre>

                <pre style="height: 100%;"><code style="min-height: 100%;font-size:30px;">
                    app.provider('greeting', function() {
  var text = 'Hello, ';

  this.setText = function(value) {
     text = value;
  };

  this.$get = function() {
     return function(name) {
         alert(text + name);
     };
  };
});

app.config(function(greetingProvider) {
  greetingProvider.setText("Howdy there, ");
});

app.run(function(greeting) {
  greeting('Ford Prefect');
});
                        </code></pre>
            </section>
            <section style="font-size: 25px">
                <p>注意这里config方法注入的是greetingProvider，上面定义了一个供应商叫greeting，但是注入到config中不能直接写greeting，
                    因为前文讲了注入的那个东西就是服务，是供应商提供出来的，而config中又只能注入供应商（两个例外是$provide和$injector），
                    所以用驼峰命名法写成greetingProvider，Angular就会帮你注入它的供应商。</p>
                <p>
                    factorry和value等服务与provider都是提供服务，为什么还有人要使用provider。答案是provider允许我们进行一些配置。
                    在前面我们已经提到过当你通过provider（或者其他简写方法）创建一个服务时，你实际上创建了一个新的provider，
                    它将定义我们的服务如何被创建。这些provider可以被注入到config函数中，我们可以和它们进行一些交互。如上文例子：
                </p>
                <p>
                    AngularJS分两个阶段运行我们的用 – config阶段和run阶段。config阶段是我们设置任何的provider的阶段。
                    它也是我们设置任何的指令，控制器，过滤器以及其它东西的阶段。在run阶段，AngularJS会编译你的DOM并启动我们的应用。
                </p>
            </section>
            <section>
                <h4>总结</h4>
                所有的供应商都只被实例化一次，也就说他们都是单例的 <br>

                除了constant，所有的供应商都可以被装饰器(decorator)装饰<br>

                value就是一个简单的可注入的值<br>

                service是一个可注入的构造器<br>

                factory是一个可注入的方法<br>

                decorator可以修改或封装其他的供应商，当然除了constant<br>

                provider是一个可配置的factory<br>
            </section>
        </section>

        <section>
            <h3>7.参考文献</h3>
            <p>参考一：
                <a href="https://segmentfault.com/a/1190000003096933"
                   target="_blank">AngularJS中的Provider们：Service和Factory等的区别</a>
            </p>
            <p>参考二：
                <a href="http://www.html-js.com/article/1980"
                   target="_blank">理解AngularJS中的依赖注入</a>
            </p>
        </section>
        <section>
            <h3>8.更多讨论</h3>
        </section>
        <section>
            <h4>鸣谢</h4>
            <p>感谢大家观看</p>
            <p>
                <small>BY :蓝裕伟</small>
            </p>
        </section>
    </div>
</div>

<script src="../lib/reveal/js/head.min.js"></script>
<script src="../lib/reveal/reveal.js"></script>

<script>
    // 以下为常见配置属性的默认值
    // {
    // 	controls: true, // 是否在右下角展示控制条
    // 	progress: true, // 是否显示演示的进度条
    // 	slideNumber: false, // 是否显示当前幻灯片的页数编号，也可以使用代码slideNumber: 'c / t' ，表示当前页/总页数。
    // 	history: false, // 是否将每个幻灯片改变加入到浏览器的历史记录中去
    // 	keyboard: true, // 是否启用键盘快捷键来导航
    // 	overview: true, // 是否启用幻灯片的概览模式，可使用"Esc"或"o"键来切换概览模式
    // 	center: true, // 是否将幻灯片垂直居中
    // 	touch: true, // 是否在触屏设备上启用触摸滑动切换
    // 	loop: false, // 是否循环演示
    // 	rtl: false, // 是否将演示的方向变成RTL，即从右往左
    // 	fragments: true, // 全局开启和关闭碎片。
    // 	autoSlide: 0, // 两个幻灯片之间自动切换的时间间隔（毫秒），当设置成 0 的时候则禁止自动切换，该值可以被幻灯片上的 ` data-autoslide` 属性覆盖
    // 	transition: 'default', // 切换过渡效果，有none/fade/slide/convex/concave/zoom
    // 	transitionSpeed: 'default', // 过渡速度，default/fast/slow
    // 	mouseWheel: true, //是否启用通过鼠标滚轮来切换幻灯片
    // }
    // 初始化幻灯片
    Reveal.initialize({
        history: true,
        dependencies: [
            {src: '../plugin/markdown/marked.js'},
            {src: '../plugin/markdown/markdown.js'},
            {src: '../plugin/notes/notes.js', async: true},
            {
                src: '../plugin/highlight/highlight.js', async: true, callback: function () {
                hljs.initHighlightingOnLoad();
            }
            }
        ]
    });
</script>
</body>

</html>
Contact GitHub API Training Shop Blog About © 2016 GitHub, Inc. Terms Privacy Security Status He